package com.kun.kunes.controller;

import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.elasticsearch.core.search.FieldSuggester;
import co.elastic.clients.elasticsearch.core.search.Suggester;
import co.elastic.clients.util.ObjectBuilder;
import com.kun.kunes.entity.JdContent;
import com.kun.kunes.util.JsoupHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * @author kun.li
 */
@RestController
@RequestMapping("/search")
public class SearchController {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Autowired
    private JsoupHelper jsoupHelper;


    @GetMapping("/{keyword}/{page}/{size}")
    public List<JdContent> jdContentList(@PathVariable String keyword,
                                         @PathVariable int page,
                                         @PathVariable int size) {

        // 爬取数据,同步到es中
        try {
            List<JdContent> jdDataList = jsoupHelper.getJdDataList(keyword);
            elasticsearchOperations.save(jdDataList, IndexCoordinates.of("jd_search"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 查询
        NativeQueryBuilder queryBuilder = NativeQuery.builder();
        NativeQuery nativeQuery = queryBuilder
                .withQuery(QueryBuilders.match().field("name").query(keyword).build()._toQuery())
                .withPageable(PageRequest.of(page, size))
                .build();
        SearchHits<JdContent> jdContentSearchHits = elasticsearchOperations.search(nativeQuery, JdContent.class, IndexCoordinates.of("jd_search"));
        List<JdContent> jdContents = new ArrayList<>();
        for (SearchHit<JdContent> jdContentSearchHit : jdContentSearchHits) {
            JdContent content = jdContentSearchHit.getContent();
            jdContents.add(content);
        }

        return jdContents;
    }

    @GetMapping("autoCompletionDataList/{keyword}")
    public List<String> autoCompletionDataList(@PathVariable String keyword) {
        List<String> autoCompletionDataList = new ArrayList<>();
        // 查询
        NativeQueryBuilder queryBuilder = NativeQuery.builder();
        queryBuilder.withSuggester(Suggester.of(builder -> {
            FieldSuggester fieldSuggester = FieldSuggester.of(new Function<FieldSuggester.Builder, ObjectBuilder<FieldSuggester>>() {
                @Override
                public ObjectBuilder<FieldSuggester> apply(FieldSuggester.Builder builder) {
                    return builder.prefix(keyword).completion(builder2 -> builder2.field("name.suggest").skipDuplicates(true).size(5));
                }
            });
            return builder.suggesters("my-suggest", fieldSuggester);
        }));
        SearchHits<JdContent> jdContentSearchHits = elasticsearchOperations.search(queryBuilder.build(), JdContent.class, IndexCoordinates.of("jd_search"));
        Suggest suggest = jdContentSearchHits.getSuggest();
        for (Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> entry : suggest.getSuggestion("my-suggest").getEntries()) {

            List<? extends Suggest.Suggestion.Entry.Option> options = entry.getOptions();
            for (Suggest.Suggestion.Entry.Option option : options) {
                autoCompletionDataList.add(option.getText());
            }

        }

        return autoCompletionDataList;
    }


}
